package com.weiqiao.api.service.impl;

import com.google.gson.Gson;
import com.mingsoft.util.MD5Util;
import com.mingsoft.util.StringUtil;
import com.mongodb.client.model.Filters;
import com.weiqiao.api.domain.*;
import com.weiqiao.api.domain.dto.TeamApiEntityDTO;
import com.weiqiao.api.domain.vo.AppUserLoginVO;
import com.weiqiao.api.domain.vo.AppUserUpdateApiVO;
import com.weiqiao.api.domain.vo.AppUserVo;
import com.weiqiao.api.domain.vo.ReceiptApiVO;
import com.weiqiao.api.repository.*;
import com.weiqiao.api.service.IAppUserApiService;
import com.weiqiao.api.until.ApiResUtil;
import com.weiqiao.api.until.RandomUtils;
import com.weiqiao.modules.basic.base.constant.entity.ResourcesEnum;
import com.weiqiao.utils.DateUtil;
import org.apache.commons.collections.CollectionUtils;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @author ChenYF
 * @Description
 * @Date 2020/7/27 19:08
 */
@Service("AppUserApiServiceImpl")
public class AppUserApiServiceImpl implements IAppUserApiService {

    @Autowired
    private IAppuserApiRepository appuserApiRepository;

    /**
     * 用户收支流水
     */
    @Autowired
    private IAccountDetailApiRepository accountDetailRepository;

    /**
     * 店铺设置
     */
    @Autowired
    private IShopkeeperApiRepository shopkeeperApiRepository;

    /**
     * 团队
     */
    @Autowired
    private ITeamApiRepository teamApiRepository;

    /**
     * 提现数据层
     */
    @Autowired
    private IReceiptApiRepository receiptApiRepository;

    /**
     * 订单数据层，获取总数
     */
    @Autowired
    private IOrderApiRepository orderApiRepository;

    @Override
    public AppUserApiEntity addUser(Integer company_id, AppUserApiEntity user) {
        boolean bool = appuserApiRepository.addUser(company_id, new Document("user_id", user.getUser_id()), new Gson().toJson(user));
        return bool ? user : null;
    }

    @Override
    public boolean updateUser(Integer company_id, AppUserApiEntity user) {
        boolean bool = appuserApiRepository.updateAppUser(
                company_id,
                new Document("user_id", user.getUser_id()),
                Document.parse(new Gson().toJson(user)),
                false
        );
        return bool;
    }

    @Override
    public AppUserApiEntity getUser(Integer company_id, String unionid) {
        String s = appuserApiRepository.getAppUserByFilter(company_id, Filters.eq("unionid", unionid));
        AppUserApiEntity entity = StringUtil.isBlank(s) ? null : new Gson().fromJson(s, AppUserApiEntity.class);
        return entity;
    }

    @Override
    public AppUserApiEntity getUser(Integer company_id, Bson filter) {
        String s = appuserApiRepository.getAppUserByFilter(company_id, filter);
        AppUserApiEntity entity = StringUtil.isBlank(s) ? null : new Gson().fromJson(s, AppUserApiEntity.class);
        return entity;
    }


    // 获取最大的用户id
    @Override
    public int getAppUserMaxId(Integer company_id) {
        Bson sort = Filters.eq("user_id", -1);
        List<String> list = appuserApiRepository.getUserBySort(company_id, new Document(), sort);
        int userId = 100000;
        if (CollectionUtils.isNotEmpty(list)) {
            AppUserApiEntity user = new Gson().fromJson(list.get(0), AppUserApiEntity.class);
            userId = user.getUser_id();
        }
        return userId;
    }

    @Override
    public ApiResponseEntity updateUser(AppUserUpdateApiVO vo) {
        Integer company_id = vo.getCompany_id();
        // 查询条件
        Document conditionDoc = new Document()
                .append("user_id", vo.getUser_id())
                .append("company_id", company_id);
        // 修改内容
        boolean is_update = false;
        Document updateDoc = new Document();
        // 修改手机号
        if (!StringUtil.isBlank(vo.getPhone())) {
            // 通过手机号查询后台是否有创建过该手机号的账号
            AppUserApiEntity user = getUser(company_id, new Document("phone", vo.getPhone()));
            if (StringUtil.isBlank(user)) {
                updateDoc.append("phone", vo.getPhone());
                is_update = true;
            } else {
                // 判断该账号是否有被合并过
                if (StringUtil.isBlank(user.getUnionid())) {
                    // 合并账号
                    updateDoc.append("member_type", user.getMember_type());
                    updateDoc.append("active_team", user.getActive_team());
                    updateDoc.append("user_name", user.getUser_name());
                    updateDoc.append("phone", user.getPhone());
                    // 删除合并前的账号
                    appuserApiRepository.delUser(company_id, new Document("user_id", user.getUser_id()));
                    // 修改当前用户的下级邀请人id
                    appuserApiRepository.updateAppUser(company_id,
                            new Document("recommend_id", user.getUser_id()),
                            new Document("recommend_id", vo.getUser_id()),
                            true
                    );

                    // 修改当前用户信息
                    boolean bool = appuserApiRepository.updateAppUser(company_id,
                            conditionDoc,
                            updateDoc,
                            false
                    );
                    return ApiResUtil.buildRes(bool, "修改用户信息成功！", getUser(company_id, conditionDoc));
                } else {
                    // 提示该手机已经被绑定过
                    return ApiResUtil.buildRes(false, ResourcesEnum.GROUP_31.getMessage());
                }
            }
        }
        // 修改用户密码
        if (!StringUtil.isBlank(vo.getPassword())) {
            String salt = RandomUtils.generateString(6);// 生成盐值
            updateDoc.append("salt", salt);
            updateDoc.append("password", MD5Util.MD5Encode(vo.getPassword() + salt, null));
            is_update = true;
        }
        // 兑换方式
        if (!StringUtil.isBlank(vo.getQrcode())) {
            if (vo.getExchange_type() == 0) {
                updateDoc.append("alipay_2dimension_Code", vo.getQrcode());
            } else {
                updateDoc.append("wechat_2dimension_Code", vo.getQrcode());
            }
            is_update = true;
        }
        // 用户头像
        if (!StringUtil.isBlank(vo.getIcon_url())) {
            updateDoc.append("icon_url", vo.getIcon_url());
            is_update = true;
        }
        if (is_update) {
            boolean bool = appuserApiRepository.updateAppUser(company_id, conditionDoc, updateDoc, false);
            return ApiResUtil.buildRes(bool, "修改用户信息成功！", getUser(company_id, conditionDoc));
        } else {
            return ApiResUtil.buildRes(false, "修改用户信息失败！");
        }
    }

    @Override
    public ApiResponseEntity userLogin(AppUserLoginVO vo) {
        Integer company_id = vo.getCompany_id();
        // 根据电话号获取当前用户是否存在，不存在抛出异常
        AppUserApiEntity entity = this.getUser(company_id, new Document("phone", vo.getPhone()));
        if (entity.getUser_state() == 1) {
            return ApiResUtil.buildRes(false, "该账号已被冻结，请联系管理员！");
        }
        if (StringUtil.isBlank(entity.getPhone())) {
            return ApiResUtil.buildRes(false, ResourcesEnum.GROUP_35.getMessage());
        }
        if (StringUtil.isBlank(vo.getPassword())) {
            return ApiResUtil.buildRes(false, ResourcesEnum.GROUP_32.getMessage());
        }
        // 判断用户是否有密码
        if (StringUtil.isBlank(entity.getPassword()) || StringUtil.isBlank(entity.getSalt())) {
            return ApiResUtil.buildRes(false, ResourcesEnum.GROUP_36.getMessage());
        }
        // 判断密码是否正确
        if (!entity.getPassword().equalsIgnoreCase(MD5Util.MD5Encode(vo.getPassword() + entity.getSalt(), null))) {
            return ApiResUtil.buildRes(false, ResourcesEnum.GROUP_37.getMessage());
        }
        // 登录成功返回接口调用凭证token
        entity.setAuth_token(MD5Util.MD5Encode(String.valueOf(System.currentTimeMillis()), null));

        // 更新当前APP用户信息
        Document doc = new Document()
                .append("device", vo.getDevice())
                .append("device_name", vo.getDevice_name())
                .append("ip_address", vo.getIp_address())
                .append("last_time", String.valueOf(System.currentTimeMillis()))
                .append("auth_token", entity.getAuth_token());
        Document filter = new Document("phone", vo.getPhone()).append("user_id", entity.getUser_id());
        boolean bool = appuserApiRepository.updateAppUser(company_id, filter, doc, false);
        return ApiResUtil.buildRes(bool, "用户登录", entity);
    }

    @Override
    public List<AccountDetailApiEntity> findAccountDetailsByFilter(AppUserVo vo) {

        // 查询条件拼接
        Document doc = getAccountDetailFilter(vo);
        Bson filter = new Document("creat_time", -1);
        int skip = vo.getPage() * vo.getSize();
        int limit = vo.getSize();
        List<String> list = accountDetailRepository.getAccountDetailByFilterSortLimit(vo.getCompany_id(), doc, filter, skip, limit);
        List<AccountDetailApiEntity> accountDetailEntityList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            for (String detailStr : list) {
                AccountDetailApiEntity entity = new Gson().fromJson(detailStr, AccountDetailApiEntity.class);
                accountDetailEntityList.add(entity);
            }
        }
        return accountDetailEntityList;
    }

    @Override
    public double getWithdrawalLimit(AppUserVo vo) {
        Document filter = new Document("company_id", vo.getCompany_id());
        String info = shopkeeperApiRepository.getOne(filter);
        if (StringUtil.isBlank(info)) {
            return 0;
        }
        ShopkeeperApiEntity entity = new Gson().fromJson(info, ShopkeeperApiEntity.class);
        return entity.getReceipt_limit();
    }

    @Override
    public ShopkeeperApiEntity getShopEntity(Bson filter) {
        String info = shopkeeperApiRepository.getOne(filter);
        if (StringUtil.isBlank(info)) {
            return new ShopkeeperApiEntity();
        }
        return new Gson().fromJson(info, ShopkeeperApiEntity.class);
    }

    @Override
    public ApiResponseEntity userWithdrawal(ReceiptApiVO receiptVO) {
        // 提现金额
        double advancePay = receiptVO.getAdvance_pay();
        if (advancePay == 0.0) {
            return ApiResUtil.buildRes(false, "价格不能为0");
        }
        HashMap<String, String> map = new HashMap<>();
        Document document = new Document("user_id", receiptVO.getUser_id());
        AppUserApiEntity userEntity = getUser(receiptVO.getCompany_id(), document);
        // 获取商户配置信息
        Document shopDocument = new Document("company_id", receiptVO.getCompany_id());
        String info = shopkeeperApiRepository.getOne(shopDocument);
        ShopkeeperApiEntity shop = new Gson().fromJson(info, ShopkeeperApiEntity.class);
        if (userEntity.getScore() < shop.getReceipt_limit() || userEntity.getScore() < advancePay) {
            return ApiResUtil.buildRes(false, "参数错误");
        }
        // 提现方式
        int withdrawType = receiptVO.getPayment();
        // 1.更新用户信息
        Document updateUser = new Document("score", userEntity.getScore() - advancePay);
        appuserApiRepository.updateAppUser(receiptVO.getCompany_id(), document, updateUser, false);

        // 添加记录
        ReceiptApiEntity receiptEntity = new ReceiptApiEntity();
        receiptEntity.setReceipt_no(String.valueOf(System.currentTimeMillis()));
        receiptEntity.setUnionid(userEntity.getUnionid());
        receiptEntity.setUser_id(userEntity.getUser_id());
        receiptEntity.setMember_type(userEntity.getMember_type());
        receiptEntity.setApply_date(receiptEntity.getReceipt_no());
        receiptEntity.setCompany_id(userEntity.getCompany_id());
        receiptEntity.setAdvance_pay(advancePay);
        receiptEntity.setPhone(userEntity.getPhone());
        receiptEntity.setAmount_total(userEntity.getScore());
        receiptEntity.setNickname(userEntity.getNickname());
        // 处理状态
        receiptEntity.setPayment(withdrawType);
        receiptEntity.setEquipment_type(0);
        receiptEntity.setDeal_state(0);
        if (1 == withdrawType) {
            receiptEntity.setAccount_information(userEntity.getIcon_url()); // 支付宝二维码
        } else if (2 == withdrawType) {
            receiptEntity.setAccount_information(userEntity.getIcon_url()); // 微信二维码
        }
        // 2.添加提现记录
        receiptApiRepository.addReceipt(userEntity.getCompany_id(), new Gson().toJson(receiptEntity));

        // 3.添加积分流水
        AccountDetailApiEntity detailEntity = new AccountDetailApiEntity();
        detailEntity.setAccount_no(String.valueOf(System.currentTimeMillis()));
        // 提现金额
        detailEntity.setAccount_money(advancePay);
        detailEntity.setPhone(userEntity.getPhone());
        // 佣金提现
        detailEntity.setHappen_proceed(1);
        // 支出
        detailEntity.setAccount_state(1);
        detailEntity.setAccount_type(1);
        // 提现地址，二维码
        detailEntity.setAccount_information(receiptVO.getAccount_information());
        detailEntity.setUser_id(userEntity.getUser_id());
        detailEntity.setName(userEntity.getNickname());
        detailEntity.setIcon_url(userEntity.getIcon_url());
        detailEntity.setRemark("积分提现");
        detailEntity.setResult_type(0);
        detailEntity.setDelete_flag(0);
        detailEntity.setCompany_id(receiptVO.getCompany_id());
        detailEntity.setCreat_time(String.valueOf(System.currentTimeMillis()));
        detailEntity.setWithdraw_type(withdrawType);
        accountDetailRepository.addAccountDetail(receiptVO.getCompany_id(), new Gson().toJson(detailEntity));
        map.put("account_no", detailEntity.getAccount_no());
        return ApiResUtil.buildRes(true, "", new Gson().toJson(map));
    }

    private Document getAccountDetailFilter(AppUserVo vo) {
        Document doc = new Document("user_id", vo.getUser_id());
        return doc;
    }

    /**
     * 分页获取内容
     *
     * @param companyId
     * @param filter
     * @param page
     * @param limit
     * @return
     */
    private List<AppUserApiEntity> getPageList(int companyId, Bson filter, int page, int limit) {
        List<AppUserApiEntity> list = new ArrayList<>();
        Bson sort = new Document("create_time", -1);
        int skip = page * limit;
        List<String> array = appuserApiRepository.getPageList(companyId, filter, sort, skip, limit);
        if (CollectionUtils.isEmpty(array)) return list;
        Gson gson = new Gson();
        for (String info : array) {
            AppUserApiEntity entity = gson.fromJson(info, AppUserApiEntity.class);
            list.add(entity);
        }
        return list;
    }

    @Override
    public ApiResponseEntity getCustomer(AppUserVo vo) {
        // 查询条件，是自己的下级，且下过单
        Document doc = new Document("recommend_id", vo.getUser_id()).append("personal_orders", new Document("$gt", 0));
        List<AppUserApiEntity> list = this.getPageList(vo.getCompany_id(), doc, vo.getPage(), vo.getSize());
        list.forEach(info -> {
            // 最后交易时间，转时间
            if (StringUtil.isLong(info.getLast_buy_time())) info.setLast_buy_time(DateUtil.timestampToString(info.getLast_buy_time()));
        });
        return ApiResUtil.buildRes(true, "", list);
    }


    @Override
    public ApiResponseEntity getTeam(AppUserVo vo) {
        List<TeamApiEntityDTO> list = new ArrayList<>();
        Document filter = new Document("delete_flag", 0);
        AppUserApiEntity user = this.getUser(vo.getCompany_id(), new Document("user_id", vo.getUser_id()));
        if (StringUtil.isBlank(user)) {
            return ApiResUtil.buildRes(false, "", list);
        }
        if (user.getMember_type() == 3) {
            // 省长查自己创建的团队
            filter.append("create_id", user.getUser_id());
        } else {
            // 团长，分销员查询自己所属团队
            filter.append("team_id", user.getTeam_id());
        }
        List<String> array = teamApiRepository.getTeamList(vo.getCompany_id(), filter);
        if (CollectionUtils.isEmpty(array)) {
            return ApiResUtil.buildRes(true, "", list);
        }
        // 当前月时间戳
        String curr = DateUtil.format(new Date(), "yyyy-MM");
        String month = "" + DateUtil.getYearsByYM(curr);
        Gson gson = new Gson();
        for (String info : array) {
            TeamApiEntityDTO entity = gson.fromJson(info, TeamApiEntityDTO.class);
            // 直推人数，即邀请人是自己
            int countUserNum = appuserApiRepository.countInfoNum(vo.getCompany_id(), new Document("recommend_id", vo.getUser_id()));
            entity.setUser_num(countUserNum);
            // 团队总人数，即在同一个团队的，team_id相同
            int countTotalNum = appuserApiRepository.countInfoNum(vo.getCompany_id(), new Document("team_id", entity.getTeam_id()));
            entity.setTotal_user(countTotalNum);
            // 本月团队申卡数,这个通过订单汇总,查询条件：当前月 + 当前团队
            Document orderFilter = new Document("create_date", new Document("$gte", month)).append("team_id", entity.getTeam_id());
            int countOrderNum = orderApiRepository.countInfoNum(vo.getCompany_id(), orderFilter);
            entity.setCard_num(countOrderNum);
            // 本月总业绩，团队总业绩，通过收支流水进行汇总,查询条件：当前月 + 佣金收入 + 当前团队 + 已结算
            Document accountFilter = new Document("creat_time", new Document("$gte", month));
            accountFilter.append("happen_proceed", 0);
            accountFilter.append("team_id", entity.getTeam_id());
            accountFilter.append("result_type", 1);
            entity.setComplete_money(this.getAccountMoney(vo.getCompany_id(), accountFilter));
            list.add(entity);
        }
        return ApiResUtil.buildRes(true, "", list);
    }

    private double getAccountMoney(int companyId, Document filter) {
        double num = 0;
        List<String> list = accountDetailRepository.getListByFilter(companyId, filter);
        if (CollectionUtils.isNotEmpty(list)) {
            Gson gson = new Gson();
            for (String info : list) {
                AccountDetailApiEntity entity = gson.fromJson(info, AccountDetailApiEntity.class);
                num += entity.getAccount_money();
            }
        }
        return num;
    }
}
